#!/usr/bin/perl

use strict;
use POSIX qw(setsid);
use Date::Calc qw(Add_Delta_Days);
use DBI; 

#flush the buffer
$| = 1;

#######   Temp data###############
my @path_prefix;
my @files_type;
my $host;
my $port;
my $database;
my $login;
my $password;
my $rescan_time;
my $days_back;
&load_config;
##################################


my $dns = "DBI:Oracle:host=$host;sid=$database;port=$port";

#daemonize the programm
&daemonize;

#our infinite loop
while (1) {
	foreach my $temp (@path_prefix) {
		my $conf = $temp;
		$conf =~ s/(^\s*"*)|("*\s*$)//g;
		$conf =~ s/"\s*=>\s*"/|/;
		my @temp = $conf =~ /([\/,\.,\w]*)/g;
		@temp = grep(/[\/,\w*,\.]+/,@temp);
		read_and_load_files($days_back, $temp[0], $temp[1], $temp[2]);
	}
	sleep($rescan_time);
}

sub daemonize {
	chdir '/'			or die "Can't chdir to /: $!";
	open STDIN, '/dev/null'	or warn "Can't read /dev/null: $!";
	open STDOUT, '>>/dev/null'	or warn "Can't write to /dev/null: $!";
	open STDERR, '>>/dev/null'	or warn"Can't write to /dev/null: $!";
	defined(my $pid = fork) 	or die "Can't fork: $!";
	exit if $pid;
	setsid				or die "Can't start a new session: $!";
	umask 0;
}

sub load_config
{
	# Loading config data
	open(CFH,"<","$ENV{HOME}/.loaderd.conf") or die "Can't read config file at $ENV{HOME}\n"; 
	my $config_data;

	while($config_data = <CFH>){
		chomp($config_data); #no newline
		$config_data =~ s/#.*//; #no comments
		$config_data =~ s/^\s+//; #no leading white
		next unless length($config_data);
		if ($config_data =~ /(paths_and_types)/i){ #|(\()|(=>)|(\))/i) {
			#files paths and format
			@path_prefix = $config_data =~ /("[\/,\.,\w]+"\s*=>\s*"\w*"\s*=>\s*"\w*")|("[\/,\.,\w]+"\s*=>\s*"\w*")/g;
			@path_prefix = grep(/[\/,\.,=,>,\w]+/, @path_prefix);
#			print("@path_prefix\n");
		}
		elsif ($config_data =~ /db_host/i) {
			#DB Host data
			$host = get_config($config_data,"db_host");
		}
		elsif ($config_data =~ /port/i) {
			#DB Port data
			$port = get_config($config_data,"port");
		}
		elsif ($config_data =~ /database/i) {
			#DB name
			$database = get_config($config_data,"database");
		}
		elsif ($config_data =~ /login/i) {
			#User login
			$login = get_config($config_data,"login");
		}
		elsif ($config_data =~ /password/i) {
			#User password
			$password = get_config($config_data,"password");
		}
		elsif ($config_data =~ /days_back/i) {
			#Days for loking back
			$days_back = get_config($config_data,"days_back");
		}
		elsif ($config_data =~ /rescan_time/i) {
			#Time for rescan folders
			$rescan_time = get_config($config_data,"rescan_time");
		}
	}

	close(CFH);
}

sub get_config
{
	my $config_data = $_[0];
	my $param_name = $_[1];
	if ($config_data =~ /$param_name/i) {
		$config_data =~ s/([\w,\s,=]*")//;
		$config_data =~ s/"\s*//;
	}
	else {
		$config_data = '';
	}
	return $config_data;
}

sub read_and_load_files
{
	my $days_back = $_[0];
	my $path_prefix = $_[1];
	my $files_type = $_[2];
	my $nesting_level = $_[3];

	if ($nesting_level =~ /^\s*$/) 	{
		$nesting_level = 0;
	}

	my $dbh = DBI->connect($dns,$login,$password) or die "$DBI::errstr\n";
	$path_prefix =~ s/\/*$//; #Delete last / if exist

	my $nday;
	my $nmonth;
	my $nyear;
	($nday,$nmonth,$nyear) = (localtime)[3,4,5];
	while ($days_back>=0) {
		my $day;
		my $month;
		my $year;
		($year, $month, $day) = Add_Delta_Days(($nyear+1900),($nmonth+1),$nday,-$days_back);	
		my $dh; #Dir handler

		my $path = "$path_prefix/".calculate_path($nesting_level,$year,$month,$day); #Dir path

		opendir ($dh,$path);
		my $file_name;

		FILE_LOOP:
			while ( defined($file_name = readdir($dh)) ) {
				next FILE_LOOP if $file_name =~ /^\.\.&$/; #miss "." and ".."
				next FILE_LOOP if $file_name =~ /^tmp-/; #Next file if this is temp file
				my $fh;
				open($fh,"<",$path.$file_name) or print STDERR "Can't open file $file_name";
				next FILE_LOOP if -d $fh; #next file if $fh is directory
				close($fh);
				my $sth = $dbh->prepare("BEGIN load_data.sf_add('$path','$file_name','$files_type');	COMMIT; END;");
				$sth->execute();
				$sth->finish();
			}
		close($dh);
		$days_back--;
	}
	$dbh->disconnect();
}

sub calculate_path
{
	my $level = $_[0];
	my $subdirYYYY = $_[1];
	my $subdirYYYYMM = "$subdirYYYY-".sprintf("%02d",$_[2]);
	my $subdirYYYYMMDD = $subdirYYYYMM."-".$_[3];
	my $path = '';
	if ($level = -3) {
		$path = $subdirYYYY."/".$subdirYYYYMM."/".$subdirYYYYMMDD."/";
	}
	elsif ($level = -2) {
		$path = $subdirYYYYMM."/".$subdirYYYYMMDD."/";
	}
	elsif ($level = -1) {
		$path = $subdirYYYYMMDD."/";
	}
	elsif ($level = 1) {
		$path = $subdirYYYY."/";
	}
	elsif ($level = 2) {
		$path = $subdirYYYY."/".$subdirYYYYMM."/";
	}
	elsif ($level = 3)
	{
		$path = $subdirYYYY."/".$subdirYYYYMM."/".$subdirYYYYMMDD."/";
	}
	return $path;
}
